package com.globallogic.training.javase.university.curriculum;

import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;

import com.globallogic.training.javase.university.member.Group;
import com.globallogic.training.javase.university.member.Instructor;

/**
 * Subject is a unit of teaching that typically lasts one academic term, is led
 * by one or more instructors (teachers or professors), and has a fixed roster
 * of groups.
 * 
 * @author Artem.Zeltinsh
 */
public class Subject implements Comparable<Subject> {

	private String id;

	private String title;

	private String description;

	private Set<Group> groups;

	private Set<Activity> activities;

	private Set<Instructor> instructors;

	public Subject(String id, String title) {
		this.id = id;
		this.title = title;
		groups = new HashSet<Group>();
		activities = new LinkedHashSet<Activity>();
		instructors = new LinkedHashSet<Instructor>();
	}

	public String getId() {
		return id;
	}

	public String getTitle() {
		return title;
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public boolean enroll(Group group) {
		return groups.add(group);
	}

	public boolean enroll(Set<Group> groups) {
		return this.groups.addAll(groups);
	}

	public Set<Group> getGroups() {
		return groups;
	}

	public Activity createActivity(ActivityType type, String id, String topic) {
		Activity activity = null;

		if (type == ActivityType.LECTURE) {
			activity = new Lecture(id, this, topic);
		} else if (type == ActivityType.SEMINAR) {
			activity = new Seminar(id, this, topic);
		} else {
			activity = new Exam(id, this, topic);
		}
		activities.add(activity);

		return activity;
	}

	public Activity getActivity(String id) {
		for (Activity activity : activities) {
			if (activity != null && activity.getId().equals(id)) {
				return activity;
			}
		}

		return null;
	}

	public boolean removeActivity(Activity a) {
		return activities.remove(a);
	}

	public void addInstructor(Instructor instructor) {
		instructors.add(instructor);
	}

	public Instructor getInstructor(String fullName) {
		for (Instructor nextInstructor : instructors) {
			if (nextInstructor.getFullName().equals(fullName)) {
				return nextInstructor;
			}
		}

		return null;
	}
	
	Instructor getDefaultInstructor() {
		return instructors.iterator().next();
	}

	public void removeInstructor(Instructor instructor) {
		instructors.remove(instructor);
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;

		return prime * result + id.hashCode();
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}

		if (getClass() != obj.getClass()) {
			return false;
		}

		Subject other = (Subject) obj;
		if (id.equals(other.id)) {
			return true;
		}

		return false;
	}

	public int compareTo(Subject other) {
		if (this == other) {
			return 0;
		}

		return this.id.compareTo(other.id);
	}

	public String toString() {
		return id + "-" + title;
	}
}
